package api.tools;

import api.VoucherFileInfo;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * PDF提取工具
 */
public class PDFTool {

    /**
     * 从PDF中提取XBRL文件
     * @param pdfPath
     * @param xbrlFileName
     * @return
     */
    public static VoucherFileInfo extractXBRLFileFromPDF(String pdfPath, String xbrlFileName, String outputFile) {
        PDDocument document = null;
        try {
            document = PDDocument.load(new File(pdfPath));
            PDDocumentNameDictionary namesDictionary = new PDDocumentNameDictionary(document.getDocumentCatalog());
            PDEmbeddedFilesNameTreeNode efTree = namesDictionary.getEmbeddedFiles();
            if (efTree != null) {
                Map<String, PDComplexFileSpecification> names = efTree.getNames();
                if (names != null) {
                    return extractFiles(names, xbrlFileName, outputFile);
                } else {
                    List<PDNameTreeNode<PDComplexFileSpecification>> kids = efTree.getKids();
                    for (PDNameTreeNode<PDComplexFileSpecification> node : kids) {
                        names = node.getNames();
                        return extractFiles(names, xbrlFileName, outputFile);
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("Exception while trying to read pdf document - " + e);
        } finally {
            try {
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static VoucherFileInfo extractFiles(Map<String, PDComplexFileSpecification> names, String attachName, String outputFile) throws IOException {
        for (Map.Entry<String, PDComplexFileSpecification> entry : names.entrySet()) {
            PDComplexFileSpecification fileSpec = entry.getValue();
            String filename = fileSpec.getFile();

            if(attachName.equals( filename)){
                PDEmbeddedFile embeddedFile = getEmbeddedFile(fileSpec);
                return extractFile(filename, embeddedFile, outputFile);
            }
        }
        return null;
    }

    private static VoucherFileInfo extractFile(String attachFilename, PDEmbeddedFile embeddedFile, String outputFile) throws IOException {

        VoucherFileInfo voucherFileInfo = new VoucherFileInfo();
        voucherFileInfo.setVoucherType("ntrev_gpm_issuer");
        String outFilePath = outputFile;
        if(outFilePath == null || "".equals(outFilePath)){
            outFilePath = System.getProperty("java.io.tmpdir") + File.separator + attachFilename;
        }

        File file = new File(outFilePath);
        System.out.println("Writing " + outFilePath);
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(file);
            fos.write(embeddedFile.toByteArray());
            fos.close();
        }catch (IOException e) {
            System.err.println("Exception while trying to read pdf document - " + e);
        }

        voucherFileInfo.setXbrlFilePath(outFilePath);
        return voucherFileInfo;//new File(embeddedFilename);
    }

    private static PDEmbeddedFile getEmbeddedFile(PDComplexFileSpecification fileSpec) {
        PDEmbeddedFile embeddedFile = null;
        if (fileSpec != null) {
            embeddedFile = fileSpec.getEmbeddedFileUnicode();
            if (embeddedFile == null) {
                embeddedFile = fileSpec.getEmbeddedFileDos();
            }
            if (embeddedFile == null) {
                embeddedFile = fileSpec.getEmbeddedFileMac();
            }
            if (embeddedFile == null) {
                embeddedFile = fileSpec.getEmbeddedFileUnix();
            }
            if (embeddedFile == null) {
                embeddedFile = fileSpec.getEmbeddedFile();
            }
        }
        return embeddedFile;
    }
}
